iT邦幫忙

2024 iThome 鐵人賽

DAY 12
0
自我挑戰組

硬體學習日記系列 第 12

Day-12 Verilog介紹-8 initial、Time_unit

  • 分享至 

  • xImage
  •  

今天要來分享的是verilog的其中一個語法-initial以及時間單位。

initial

initial區塊是用來定義module在開始執行時,只執行一次的區塊,這個區塊在執行時間為0時執行。通常會在初始化信號、初始化暫存器、設置初始條件時使用,以及在特定時間點後觸發某些行為。

initial的基本結構是:

initial begin
	//執行指令 eg.初始化
end

如果有一些特別的目的,希望initial區塊內的某特定指令要延遲些時間才執行的話,可以使用「#數字」,數字表示所要延遲的時間,「#15」即表示延遲15個時間單位,時間到後再繼續執行後麵的指令。
那在同一個module內,並沒有限制只能存在一個initial區塊。那如果存在好幾個initial區塊,這些區塊間的關係會是並行的,所以他們會同時執行,而每個區塊內的指令一樣會按照順序執行。

那來做個練習~

module newwork(A,B,C);
	input A,B;
	output C;
	reg clk;
	reg Q;
	reg flag;
	
	initial begin
		flag = 0;
		Q = 0;
	end
	
	initial begin
		clk = 0;
	end
	
	always begin
		#10 clk = ~clk;
	end
	
	always @( posedge clk )
	begin
		if( flag == 0 )begin
			Q = ~A;
			flag = 1;
		end
		else if( flag == 1 )begin
			Q = ~B;
			flag = 0;
		end
	end
	
	assign C = Q;
	
endmodule

一開始的flag、Q跟clk都先初始為0,然後clk每10個單位時間就反轉一次(所以這是一個週期為20個時間單位的週期性時鐘信號),而暫存器Q的內容就會隨著clk的反轉而更新,當遇到clk的rising edge時,就會交替的換成A’或B’;如果flag值為0,Q就為A’,否則為B’,然後再將Q的內容傳給output C。
在第一個always block內,就是指每10個時間單位,clk做一次反轉。

其實我本來想寫:

module newwork(A,B,C);
	input A,B;
	output C;
	reg clk;
	reg Q;
	reg flag;
	
	initial begin
		flag = 0;
		Q = 0;
	end
	
	//不同的地方
	initial begin
		clk = 0;
		forever #10 clk = ~clk;
	end
	//
	
	always @( posedge clk )
	begin
		if( flag == 0 )begin
			Q = ~A;
			flag = 1;
		end
		else if( flag == 1 )begin
			Q = ~B;
			flag = 0;
		end
	end
	
	assign C = Q;
	
endmodule

但編譯的時候,forever那行一直錯誤,日後如果有找出解決方法,再上傳來分享。

單位時間

那上面提到了時間單位,一個時間單位又是多久呢?
在verilog中,時間單位是可以自己決定的,我們可以在module中指定一個時間單位的長度,他與module工具的時鐘無關。
如何定義時間單位呢?我們會用「timescale」指令來做設置,這是他的語法:

`timescale <timeunit> / <time_precision>

其中<timeunit>負責定義了module中使用的基本時間單位,像是秒、毫秒、微秒。
<time_precision>則是定義了module中時間的精度,控制小數點後的時間表示精度。
記得!timescale前面有一個「`」符號喔!然後最後面不能加分號!

以上面舉的程式碼繼續做例子:

`timescale 1ns / 1ps

module newwork(A,B,C);
	input A,B;
	output C;
	reg clk;
	reg Q;
	reg flag;
	
	initial begin
		flag = 0;
		Q = 0;
	end
	
	initial begin
		clk = 0;
	end
	
	always begin
		#10 clk = ~clk;
	end
	
	always @( posedge clk )
	begin
		if( flag == 0 )begin
			Q = ~A;
			flag = 1;
		end
		else if( flag == 1 )begin
			Q = ~B;
			flag = 0;
		end
	end
	
	assign C = Q;
	
endmodule

這樣的話,這個程式的時間就會是以1奈秒為基礎、精確度可以到1皮秒。
所以在always block中的#10,即是代表10奈秒,所以每隔10奈秒,clk就會做一次反轉,週期為20奈秒。

那如果沒有定義時間單位,但程式中有使用到與時間有關的功能,時間單位又會是多長呢?這樣的話就會使用默認的時間單位喔,那這些值可能會因為使用的模擬器不同而不同,所以建議還是要記得定義~

那今天就到這邊~謝謝~


上一篇
Day-11 verilog介紹-7 邏輯電路
下一篇
Day-13 Verilog介紹-9 Case
系列文
硬體學習日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言